package yuhuibear.poat.util.sqlParse;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class SqlSentence {

	private static Set<String> fromEndWords = new HashSet<String>();
	static {
		fromEndWords.add("where");
		fromEndWords.add("order");
		fromEndWords.add("group");
		fromEndWords.add("limit");
		fromEndWords.add("with");
		fromEndWords.add("having");
		fromEndWords.add("offset");
	}

	private static Set<String> joinWords = new HashSet<String>();
	static {
		joinWords.add("join");
		joinWords.add("left");
		joinWords.add("right");
		joinWords.add("outer");
		joinWords.add("inner");
		joinWords.add("cross");
	}

	private static Set<String> keyWords = new HashSet<String>();
	static {
		keyWords.add("as");
		keyWords.add("on");
		keyWords.add("select");
		keyWords.add("union");
		keyWords.add("intersect");
		keyWords.add("except");
		keyWords.add("in");
		keyWords.add(",");
		keyWords.add("sum");
		keyWords.add("count");
		keyWords.add("avg");
		keyWords.add("max");
		keyWords.add("min");
	}

	private Set<String> refs = new HashSet<String>();

	private StringBuffer clause = new StringBuffer();

	private StringBuffer word = new StringBuffer();

	private boolean inFrom = false;

	private boolean inSelect = false;

	/**
	 * 压入不含' 的from 子句中的字符。
	 * 
	 * @param word
	 * @return
	 */
	public boolean pushChar(char ch, boolean prvInFrom) {
		if (ch == ' ') {
			if (word.length() > 0) {
				String str = word.toString();
				word = new StringBuffer();
				str = str.toLowerCase().trim();
				if (inFrom) {
					if (fromEndWords.contains(str)) {
						int len = clause.length();
						clause.delete(len - str.length(), len);
						inFrom = false;
						inSelect = false;
						return true;
					}

				}
				else {
					inFrom = str.equals("from");
					if (inFrom)
						inSelect = false;
					if (!inSelect) {
						inSelect = str.equals("select");
						int len = clause.length();
						if (inSelect && len > 0 && len >= word.length()) {
							clause.delete(len - str.length(), len);
						}
					}
				}
			}
		}
		else {
			word.append(ch);
		}
		if (inFrom || (!inSelect && prvInFrom))
			clause.append(ch);
		return false;
	}

	public boolean isInSelect() {
		return inSelect;
	}

	public String getWord() {
		String str = word.toString();
		word.delete(0, word.length());
		return str;
	}

	public boolean isInFrom() {
		return inFrom;
	}

	public void addToRefs(String str) {
		str = str.trim();
		if (!keyWords.contains(str) && str.length() > 0)
			refs.add(str);
	}

	public void addToRefs(Collection<String> strs) {
		for (String str : strs)
			addToRefs(str);
	}

	/**
	 * 提取参考的对象，表，视图，函数。。。
	 * 
	 * @return
	 */
	public Set<String> getRefs() {
		if (clause.length() < 1) { return refs; }
		for (String str : clause.toString().split("\\s*,\\s*")) {
			str = str.trim();
			if (str.length() < 1)
				continue;
			int idxSpace = str.indexOf(' ');
			int idxBrc = str.indexOf('(');
			int idxJoin = str.indexOf("join");
			if (idxJoin > 0) {
				addToRefs(str.substring(0, idxSpace));
				idxJoin = idxJoin + 5;
				str = str.substring(idxJoin).trim();
				idxSpace = str.indexOf(' ');
				addToRefs(str.substring(0, idxSpace));
			}
			else if (idxSpace < 0)
				if (idxBrc < 0)
					addToRefs(str);
				else addToRefs(str.substring(0, idxBrc));
			else addToRefs(str.substring(0, idxSpace));
		}
		clause = new StringBuffer();
		return refs;
	}

	public String toString() {
		return clause.toString();
	}
}
